package com.xuecheng.media.service.impl;

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.api.media.model.dto.MediaDTO;
import com.xuecheng.api.media.model.qo.QueryMediaModel;
import com.xuecheng.common.domain.code.CommonErrorCode;
import com.xuecheng.common.domain.page.PageRequestParams;
import com.xuecheng.common.domain.page.PageVO;
import com.xuecheng.common.domain.response.RestResponse;
import com.xuecheng.common.enums.common.AuditEnum;
import com.xuecheng.common.enums.common.CommonEnum;
import com.xuecheng.common.enums.common.ResourceTypeEnum;
import com.xuecheng.common.exception.ExceptionCast;
import com.xuecheng.common.util.StringUtil;
import com.xuecheng.media.common.constant.MediaErrorCode;
import com.xuecheng.media.common.utils.AliyunVODUtil;
import com.xuecheng.media.controller.MediaAudtoController;
import com.xuecheng.media.convert.MediaConvert;
import com.xuecheng.media.entity.Media;
import com.xuecheng.media.mapper.MediaMapper;
import com.xuecheng.media.service.MediaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;

@Slf4j
@Service
public class MediaServiceImpl extends ServiceImpl<MediaMapper, Media> implements MediaService {

    @Override
    public String getPlayUrlByMediaId(Long mediaId, Long companyId) {

        // 判断关键数据
        if (ObjectUtils.isEmpty(mediaId)
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }

        // 判断业务数据
        // 媒资信息是否存在
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Media::getId, mediaId);

        if (!(ObjectUtils.nullSafeEquals(companyId, MediaAudtoController.OPERATION_FLAG))) {
            queryWrapper.eq(Media::getCompanyId, companyId);
        }

        Media media = this.getOne(queryWrapper);

        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }
        // 获得媒资文件的资源路径地址
        String type = media.getType();


        String resourceUrl = null;

        if (ResourceTypeEnum.VIDEO. getCode().equals(type)) {
            resourceUrl = getAliyunVodPlayUrl(media.getFileId());
        } else if (ResourceTypeEnum.DOCUMENT.getCode().equals(type)){
            //获得的媒资文档的资源访问地址路径
        } else if (ResourceTypeEnum.WORK.getCode().equals(type)){
            //获得的媒资文档的资源访问地址路径
        }

        return resourceUrl;
    }
    private String getAliyunVodPlayUrl(String fileId) {

        String playURL = null;
        try {
            DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);

            GetPlayInfoResponse playInfo = AliyunVODUtil.getPlayInfo(client, fileId);

            List<GetPlayInfoResponse.PlayInfo> playInfoList = playInfo.getPlayInfoList();

            if (com.baomidou.mybatisplus.core.toolkit.CollectionUtils.isEmpty(playInfoList)) {
                ExceptionCast.cast(MediaErrorCode.E_140013);
            }

            // 默认获得第一个播放地址
            playURL = playInfoList.get(0).getPlayURL();
        } catch (Exception e) {
            log.error(MediaErrorCode.E_140012.getDesc()+" : {}",e.getMessage());
            ExceptionCast.cast(MediaErrorCode.E_140012);
        }

        return playURL;
    }
    @Override
    public PageVO queryMediaList(PageRequestParams params, QueryMediaModel model, Long companyId) {
        if (params.getPageNo() < 1) {
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }
        if (params.getPageSize() < 1) {
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }
        // filename如果不为空，lamb添加like
        //  type有就加上
        //  时间倒序
        //  是否删除
        //  机构id（只能查询自己机构的数据
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        if (!StringUtil.isEmpty(model.getFilename())){
            queryWrapper.like(Media::getFilename,model.getFilename());
        }
        if (!StringUtil.isEmpty(model.getAuditStatus())){
            queryWrapper.eq(Media::getAuditStatus,model.getAuditStatus());
        }
        if (!StringUtil.isEmpty(model.getType())){
            queryWrapper.eq(Media::getType,model.getType());
        }
        if (!ObjectUtils.isEmpty(companyId)){
            queryWrapper.eq(Media::getCompanyId,companyId);
        }
        queryWrapper.eq(Media::getStatus, CommonEnum.USING_FLAG.getCode());
        queryWrapper.orderByDesc(Media::getCreateDate);
        Page<Media> mediaPage = new Page<>(params.getPageNo(),params.getPageSize());
        Page<Media> vo = page(mediaPage, queryWrapper);
        List<Media> list = vo.getRecords();

        List<MediaDTO> dtoList  = Collections.emptyList();
        if (!ObjectUtils.isEmpty(list)){
            dtoList = MediaConvert.INSTANCE.entitys2dtos(list);
        }
        PageVO<MediaDTO> pageVO = new PageVO(dtoList,vo.getTotal(),params.getPageNo(),params.getPageSize());
        return pageVO;
    }
    @Transactional
    public void approve(MediaDTO dto) {
        if (ObjectUtils.isEmpty(dto.getId())||
                ObjectUtils.isEmpty(dto.getAuditMind())||
                ObjectUtils.isEmpty(dto.getAuditStatus())
        ){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        if (!(dto.getAuditStatus().equals("202002")||
                dto.getAuditStatus().equals("202001")||
                dto.getAuditStatus().equals("202003")
        )
        ){
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Media::getId,dto.getId());
        queryWrapper.eq(Media::getAuditStatus,AuditEnum.AUDIT_UNPAST_STATUS.getCode());
        Media one = getOne(queryWrapper);
        if (ObjectUtils.isEmpty(one))
        {
            ExceptionCast.cast(MediaErrorCode.E_140004);
        }
        LambdaUpdateWrapper<Media> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Media::getId,dto.getId());
        updateWrapper.set(Media::getAuditMind,dto.getAuditMind());
        updateWrapper.set(Media::getAuditStatus,dto.getAuditStatus());
        boolean update = update(updateWrapper);
        if (!update) {
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }
    }
    @Transactional
    public MediaDTO createMedia(MediaDTO dto) {

        if (ObjectUtils.isEmpty(dto.getCompanyId())||
                StringUtil.isBlank(dto.getFilename())||
                StringUtil.isBlank(dto.getFileId())
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        Media media = MediaConvert.INSTANCE.dto2entity(dto);
        media.setAuditStatus(AuditEnum.AUDIT_UNPAST_STATUS.getCode());
        media.setId(null);
        boolean result = this.save(media);
        // 判断保存后的结果并返回DTO数据
        if (!result) {
            ExceptionCast.cast(MediaErrorCode.E_140001);
        }
        Media po = this.getById(media.getId());
        MediaDTO resultDTO = MediaConvert.INSTANCE.entity2dto(po);

        return resultDTO;
    }


    @Value("${aliyun.region}")
    private String region;
    @Value("${aliyun.accessKeyId}")
    private String accessKeyId;
    @Value("${aliyun.accessKeySecret}")
    private String accessKeySecret;

    public String previewMedia(Long mediaId,Long companyId) {

        //判断关键数据
        if (ObjectUtils.isEmpty(mediaId)||
                ObjectUtils.isEmpty(companyId)
        ) {
            ExceptionCast.cast(CommonErrorCode.E_100101);
        }
        // 判断业务数据
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Media::getId, mediaId);
        queryWrapper.eq(Media::getCompanyId, companyId);

        Media media = this.getOne(queryWrapper);
        if (ObjectUtils.isEmpty(media)) {
            ExceptionCast.cast(MediaErrorCode.E_140005);
        }
        // 获得媒资预览地址
        String type = media.getType();

        String playURL = null;

        if (ResourceTypeEnum.VIDEO.getCode().equals(type)) {

            try {
                // 从阿里云视频点播中获得播放地址
                DefaultAcsClient client = AliyunVODUtil.initVodClient(region, accessKeyId, accessKeySecret);
                GetPlayInfoResponse response = AliyunVODUtil.getPlayInfo(client,media.getFileId());
                List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();
                // 默认预览操作获得第一个播放地址
                GetPlayInfoResponse.PlayInfo playInfo = playInfoList.get(0);

                playURL = playInfo.getPlayURL();
            } catch (Exception e) {
                log.error(MediaErrorCode.E_140012.getDesc()+" {}",e.getMessage());
                ExceptionCast.cast(MediaErrorCode.E_140012);
            }
        }
        return playURL;
    }

    @Override
    public PageVO<MediaDTO> queryCourseList(PageRequestParams params, QueryMediaModel model, Long companyId) {

        //判断关键数据

        if (params.getPageNo() < 0) {
            params.setPageNo(PageRequestParams.DEFAULT_PAGE_NUM);
        }
        if (params.getPageSize() < 0) {
            params.setPageSize(PageRequestParams.DEFAULT_PAGE_SIZE);
        }
        //  创建分页数据
        Page<Media> basePage = new Page<>(params.getPageNo(),params.getPageSize());
        // 构建查询条件
        LambdaQueryWrapper<Media> queryWrapper = new LambdaQueryWrapper<>();
        String filename = model.getFilename();
        String type = model.getType();
        String auditStatus = model.getAuditStatus();
        queryWrapper.like(!(StringUtil.isBlank(filename)),Media::getFilename, filename);
        queryWrapper.eq(!(StringUtil.isBlank(type)),Media::getType, type);
        queryWrapper.eq(!(StringUtil.isBlank(auditStatus)),Media::getAuditStatus, auditStatus);
        // 添加公司的id值来实现教学机构的数据隔离
        queryWrapper.eq(!(ObjectUtils.isEmpty(companyId)),Media::getCompanyId, companyId);
        // 查询数据
        Page<Media> pageResult = this.page(basePage, queryWrapper);
        List<Media> records = pageResult.getRecords();
        long total = pageResult.getTotal();
        List<MediaDTO> dtos = Collections.EMPTY_LIST;
        if (!(CollectionUtils.isEmpty(records))) {
            dtos = MediaConvert.INSTANCE.entitys2dtos(records);
        }

        // 将数据封装到PageVO
        PageVO<MediaDTO> pageVO = new PageVO(dtos,total,params.getPageNo(),params.getPageSize());
        // 返回结果
        return pageVO;
    }

    public RestResponse<MediaDTO> getMediaById4s(Long mediaId) {

        // 判断关键数据
        if (ObjectUtils.isEmpty(mediaId)) {
            return RestResponse.validfail(CommonErrorCode.E_100101);
        }
        // 根据id查询媒资信息
        Media media = this.getById(mediaId);
        if (ObjectUtils.isEmpty(media)) {
            return RestResponse.validfail(MediaErrorCode.E_140005);
        } else {
            MediaDTO mediaDTO = MediaConvert.INSTANCE.entity2dto(media);
            return RestResponse.success(mediaDTO);
        }
    }

}
